using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Speedball2 {
  public class Token {
    public int _remainingSeconds;
    public int _heldSpriteIndex;
    public Player _holdingPlayer;

    public Token () {
      _remainingSeconds = 0;
      _heldSpriteIndex = 0;
      _holdingPlayer = null;
    }

    public void Dispose (Match match) {
      if (_heldSpriteIndex == 0)
        return;
      Player player;
      if (_holdingPlayer.Bit3_IsTeam1_IsElectrobounced) {
        match.EntityStatusLed._spriteIndex = 88;
        player = match.PlayerHavingInputTeam1;
      }
      else {
        match.EntityStatusLed._spriteIndex = 89;
        player = match.PlayerHavingInputTeam2;
      }
      match.DrawStatusToken (match.EntityStatusLed, player);

      //int functionDispose = GetFunctionDispose (_heldSpriteIndex - 55);
      int functionIndex = _heldSpriteIndex - 55;
      if ((functionIndex >= 0) &&
          (functionIndex <= 1)) {
      }
      else if (functionIndex == 2)
        Dispose_ReduceTeam (match, _holdingPlayer);
      else if (functionIndex == 3)
        Dispose_IncreaseTeam (match, _holdingPlayer);
      else if (functionIndex == 4)
        Dispose_Manic (match, _holdingPlayer);
      else if (functionIndex == 5)
        Dispose_SlowTeam (match, _holdingPlayer);
      else if ((functionIndex >= 6) &&
               (functionIndex <= 15)) {
      }
      _heldSpriteIndex = 0;
    }

    public void Init_FreezeTeam (Match match, Entity token, Player player) {
      Dispose (match);
      match.DrawStatusToken (token, player);
      _remainingSeconds = 6;
      _heldSpriteIndex = 55;
      _holdingPlayer = player;
    }

    public void Init_ReverseJoystick (Match match, Entity token, Player player) {
      Dispose (match);
      match.DrawStatusToken (token, player);
      _remainingSeconds = 6;
      _heldSpriteIndex = 56;
      _holdingPlayer = player;
    }

    public void Init_ReduceTeam (Match match, Entity token, Player player) {
      Dispose (match);
      match.DrawStatusToken (token, player);
      _remainingSeconds = 6;
      _heldSpriteIndex = 57;
      _holdingPlayer = player;

      Player [] players;
      if (player.Bit3_IsTeam1_IsElectrobounced)
        players = match.PlayersTeam2;
      else
        players = match.PlayersTeam1;
      foreach (Player player2 in players)
        player2.BackupAttributesAgrEtcAndSetValue (100);
    }

    public void Init_IncreaseTeam (Match match, Entity token, Player player) {
      Dispose (match);
      match.DrawStatusToken (token, player);
      _remainingSeconds = 6;
      _heldSpriteIndex = 58;
      _holdingPlayer = player;

      Player [] players;
      if (player.Bit3_IsTeam1_IsElectrobounced)
        players = match.PlayersTeam1;
      else
        players = match.PlayersTeam2;
      foreach (Player player2 in players)
        player2.BackupAttributesAgrEtcAndSetValue (250);
    }

    public void Init_Manic (Match match, Entity token, Player player) {
      Dispose (match);
      match.DrawStatusToken (token, player);
      _remainingSeconds = 6;
      _heldSpriteIndex = 59;
      _holdingPlayer = player;

      foreach (Player player2 in match.PlayersTeam1)
        player2.BackupAttributesAgrEtcAndSetValue (250);
      foreach (Player player2 in match.PlayersTeam2)
        player2.BackupAttributesAgrEtcAndSetValue (250);
    }

    public void Init_SlowTeam (Match match, Entity token, Player player) {
      Dispose (match);
      match.DrawStatusToken (token, player);
      _remainingSeconds = 6;
      _heldSpriteIndex = 60;
      _holdingPlayer = player;

      Player [] players;
      if (player.Bit3_IsTeam1_IsElectrobounced)
        players = match.PlayersTeam2;
      else
        players = match.PlayersTeam1;
      foreach (Player player2 in players)
        player2.BackupAttributeSpdAndSet100 ();
    }

    public void Init_GrabBall (Match match, Entity token, Player player) {
      match.EntityHoldingBall = player;
      match.EntityBall._pOpcodes = 0x5588;
      match.EntityBall._opcodeIndex = 0;
      match.Bit2_IsBallInScoreMultiplier = false;
    }

    public void Init_Transport (Match match, Entity token, Player player) {
      Player player2;
      if (player.Bit3_IsTeam1_IsElectrobounced)
        player2 = match.PlayersTeam1 [8];
      else
        player2 = match.PlayersTeam2 [8];
      if (player2.Bit4_IsFalling)
        return;
      match.EntityHoldingBall = player2;
      match.EntityBall._pOpcodes = 0x5588;
      match.EntityBall._opcodeIndex = 0;
      match.Bit2_IsBallInScoreMultiplier = false;
    }

    public void Init_GoalDoor (Match match, Entity token, Player player) {
      Dispose (match);
      match.DrawStatusToken (token, player);
      _remainingSeconds = 6;
      _heldSpriteIndex = 63;
      _holdingPlayer = player;
    }

    public void Init_Shield (Match match, Entity token, Player player) {
      Dispose (match);
      match.DrawStatusToken (token, player);
      _remainingSeconds = 6;
      _heldSpriteIndex = 64;
      _holdingPlayer = player;
    }

    public void Init_FullEnergy (Match match, Entity token, Player player) {
      player.InitAttributesAndStats (match);
    }

    public void Init_ZapTeam (Match match, Entity token, Player player) {
      Player [] players = match.PlayersTeam1;
      if (player.Bit3_IsTeam1_IsElectrobounced)
        players = match.PlayersTeam2;
      foreach (Player player2 in players) {
        if (player2.Bit6_IsOffscreen)
          continue;
        if (!player2.sub_FC24 (match))
          continue;
        if (player2.Bit4_IsFalling)
          continue;
        player2.sub_EEFC_HitByTackle (match, player);
        player2._opcodeIndex = 0;
        player2.Bit0_IsBusy = true;
        player2.Bit4_IsFalling = true;
        player2._pThink = 0xF344;
        int velocity = 4;
        if (player2._velocityXY.IsEmpty)
          velocity = 3;
        player2.sub_F5A8_SetOpcodesAndVelocityFromDir (0x5EE6, velocity);
        if (player2 == match.EntityHoldingBall)
          match.EntityHoldingBall = null;
      }
    }

    public void Dispose_ReduceTeam (Match match, Player player) {
      Player [] players = match.PlayersTeam1;
      if (player.Bit3_IsTeam1_IsElectrobounced)
        players = match.PlayersTeam2;
      foreach (Player player2 in players)
        player2.RestoreAttributesAgrEtc ();
    }

    public void Dispose_IncreaseTeam (Match match, Player player) {
      Player [] players = match.PlayersTeam1;
      if (!player.Bit3_IsTeam1_IsElectrobounced)
        players = match.PlayersTeam2;
      foreach (Player player2 in players)
        player2.RestoreAttributesAgrEtc ();
    }

    public void Dispose_Manic (Match match, Player player) {
      foreach (Player player2 in match.PlayersTeam1)
        player2.RestoreAttributesAgrEtc ();
      foreach (Player player2 in match.PlayersTeam2)
        player2.RestoreAttributesAgrEtc ();
    }

    public void Dispose_SlowTeam (Match match, Player player) {
      Player [] players = match.PlayersTeam1;
      if (player.Bit3_IsTeam1_IsElectrobounced)
        players = match.PlayersTeam2;
      foreach (Player player2 in players)
        player2.RestoreAttributeSpd ();
    }

    private int GetFunctionDispose (int index) {
      int offset = 0x300C + index * 4;
      return ((int) Game.AtariDisk.ReadLong (Game.AtariRamToDisk (offset)));
    }
  }
}
